package parser.news;

import entities.News;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import parser.exception.ParserException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * Abstract class for getting news from channel resource link
 * User: kaiser
 * Date: 7/31/13
 * Time: 9:33 PM
 */
abstract class ChannelParser implements NewsParser {

    /**
     * Channel rss feed resource
     */
    protected String resource = "";

    /**
     * getting personal handler for parsing
     *
     * @return class for parse and collect news and channel information
     */
    abstract protected NewsHandler getParserHandler();

    /**
     * Get channel news resource link
     *
     * @return URL
     */
    abstract protected String getChannelResourceLink();

    @Override
    public List<News> getNews(int count) {
        try {
            SAXParser parser = getParser();
            NewsHandler handler = getParserHandler();
            handler.setLimit(count);
            parser.parse(getSource(), handler);
            return handler.getNewsList();

        } catch (ParserException e) {
            /**
             * @todo add logging
             */
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new ArrayList<News>();
    }

    /**
     * Getting XML source for its further parsing
     *
     * @return source from resource URL or null if resource is empty
     * @throws IOException
     */
    protected InputSource getSource() throws IOException, ParserException {
        if (notEmptyResource()) {
            String resource = getChannelResourceLink();
            InputStream stream = new URL(resource).openStream();
            InputSource source = new InputSource(stream);
            if (source != null) {
                return source;
            }
            throw new ParserException("Empty source for channel parser");
        }
        throw new ParserException("Empty resource for channel parser");
    }

    /**
     * Create and get SAX parser object
     *
     * @return
     * @throws ParserConfigurationException
     * @throws SAXException
     */
    protected SAXParser getParser() throws ParserConfigurationException, SAXException {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();
        return saxParser;
    }


    /**
     * Check resource is not null and not empty
     *
     * @return true if resource not null and not empty
     */
    protected boolean notEmptyResource() {
        String resource = getChannelResourceLink();

        return resource != null && !resource.isEmpty();
    }

    /**
     * Create and Getting empty ArrayList for news
     *
     * @return empty ArrayList for adding News
     */
    protected List<News> getEmptyNewsList() {
        return new ArrayList<News>();
    }
}
